{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "d1f20875-c50d-46df-906b-49ec1d0c6002",
   "metadata": {},
   "source": [
    "## 10.8 LeNet的实现\n"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "id": "c90a18b9-d8e8-431c-856c-35f1e4ed05e1",
   "metadata": {},
   "source": [
    "### 1.任务描述\n",
    "\n",
    "使用TensorFlow实现LeNet，对CIFAR-10数据集进行训练，实现多分类。"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "id": "f5b4fc39-cbcf-432a-bf1e-e75e642d4b87",
   "metadata": {},
   "source": [
    "### 2.知识准备\n",
    "\n",
    "见教程。"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "id": "55043130-4496-43a3-803b-9bc1cea8b1b8",
   "metadata": {},
   "source": [
    "### 3.任务分析\n",
    "\n",
    "定义一个LeNet5的网络实现类，在该类中定义网络结构并定义表明参数传播方向的前向传播函数。"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "435c6090-cfda-4f46-a550-22a368e41e4a",
   "metadata": {},
   "source": [
    "### 4.任务实施\n"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "id": "ec75eb6c-5da3-467d-a471-ca3b47242dd6",
   "metadata": {},
   "source": [
    "执行代码"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "2ae9da58-e339-4d22-9f8d-ca255711d89e",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch 1/5\n",
      "1563/1563 [==============================] - 12s 5ms/step - loss: 2.0469 - sparse_categorical_accuracy: 0.2315 - val_loss: 1.8848 - val_sparse_categorical_accuracy: 0.3039\n",
      "Epoch 2/5\n",
      "1563/1563 [==============================] - 7s 4ms/step - loss: 1.7891 - sparse_categorical_accuracy: 0.3393 - val_loss: 1.6747 - val_sparse_categorical_accuracy: 0.3866\n",
      "Epoch 3/5\n",
      "1563/1563 [==============================] - 7s 5ms/step - loss: 1.6395 - sparse_categorical_accuracy: 0.3979 - val_loss: 1.5765 - val_sparse_categorical_accuracy: 0.4223\n",
      "Epoch 4/5\n",
      "1563/1563 [==============================] - 7s 4ms/step - loss: 1.5738 - sparse_categorical_accuracy: 0.4243 - val_loss: 1.5495 - val_sparse_categorical_accuracy: 0.4316\n",
      "Epoch 5/5\n",
      "1563/1563 [==============================] - 7s 4ms/step - loss: 1.5223 - sparse_categorical_accuracy: 0.4423 - val_loss: 1.4976 - val_sparse_categorical_accuracy: 0.4519\n",
      "Model: \"le_net5\"\n",
      "_________________________________________________________________\n",
      " Layer (type)                Output Shape              Param #   \n",
      "=================================================================\n",
      " conv2d (Conv2D)             multiple                  456       \n",
      "                                                                 \n",
      " max_pooling2d (MaxPooling2D  multiple                 0         \n",
      " )                                                               \n",
      "                                                                 \n",
      " conv2d_1 (Conv2D)           multiple                  2416      \n",
      "                                                                 \n",
      " max_pooling2d_1 (MaxPooling  multiple                 0         \n",
      " 2D)                                                             \n",
      "                                                                 \n",
      " flatten (Flatten)           multiple                  0         \n",
      "                                                                 \n",
      " dense (Dense)               multiple                  51328     \n",
      "                                                                 \n",
      " dense_1 (Dense)             multiple                  10836     \n",
      "                                                                 \n",
      " dense_2 (Dense)             multiple                  850       \n",
      "                                                                 \n",
      "=================================================================\n",
      "Total params: 65,886\n",
      "Trainable params: 65,886\n",
      "Non-trainable params: 0\n",
      "_________________________________________________________________\n"
     ]
    }
   ],
   "source": [
    "# 1，导入模块\n",
    "import tensorflow as tf\n",
    "from tensorflow.keras.layers import Conv2D, BatchNormalization, Activation, MaxPool2D, Dropout, Flatten, Dense\n",
    "from tensorflow.keras import Model\n",
    "# 2，加载数据集\n",
    "(x_train, y_train), (x_test, y_test) = tf.keras.datasets.cifar10.load_data()\n",
    "x_train, x_test = x_train / 255.0, x_test / 255.0\n",
    "# 3，创建网络\n",
    "class LeNet5(Model):\n",
    "    def __init__(self):\n",
    "        super(LeNet5,self).__init__()\n",
    "        # 卷积层\n",
    "        self.c1=Conv2D(filters=6,kernel_size=(5,5),activation= 'sigmoid')\n",
    "        # 池化层\n",
    "        self.p1 = MaxPool2D(pool_size=(2, 2), strides=2)  \n",
    "        # 卷积层\n",
    "        self.c2=Conv2D(filters=16,kernel_size=(5,5),activation= 'sigmoid')\n",
    "        # 池化层\n",
    "        self.p2 = MaxPool2D(pool_size=(2, 2), strides=2)        \n",
    "        # 拉平层\n",
    "        self.flatten = Flatten()\n",
    "        # 隐含层\n",
    "        self.f1 = Dense(128, activation='sigmoid')\n",
    "        # 隐含层\n",
    "        self.f2 = Dense(84, activation='sigmoid')\n",
    "        # 输出层\n",
    "        self.f3 = Dense(10, activation='softmax')\n",
    "    def call(self,x):\n",
    "        x = self.c1(x)\n",
    "        x = self.p1(x)\n",
    "        x = self.c2(x)\n",
    "        x = self.p2(x)\n",
    "        x = self.flatten(x)\n",
    "        x = self.f1(x)\n",
    "        x = self.f2(x)\n",
    "        y = self.f3(x)\n",
    "        return y\n",
    "    \n",
    "# 实例化模型对象\n",
    "model = LeNet5()\n",
    "# 4，配置网络\n",
    "model.compile(\n",
    "    # 优化器\n",
    "    optimizer='adam',\n",
    "    # 损失函数\n",
    "    loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits= False),\n",
    "    # 评测方法\n",
    "    metrics=['sparse_categorical_accuracy']\n",
    ")\n",
    "\n",
    "# 5，训练网络\n",
    "history = model.fit(\n",
    "    x_train, y_train, batch_size=32, epochs=5, \n",
    "    validation_data=(x_test, y_test), validation_freq=1\n",
    ")\n",
    "model.summary()\n",
    "\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "e6044c99-0741-4378-b2b6-f60c293cc3a9",
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.9.10"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
